package com.stylefeng.guns.modular.vpnuserinfo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.base.tips.ErrorTip;
import com.stylefeng.guns.core.base.tips.SuccessTip;
import com.stylefeng.guns.core.common.constant.DatasourceEnum;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.modular.system.dao.VpnPackageInfoMapper;
import com.stylefeng.guns.modular.system.model.VpnPackageInfo;
import com.stylefeng.guns.modular.system.model.VpnUserInfo;
import com.stylefeng.guns.modular.system.dao.VpnUserInfoMapper;
import com.stylefeng.guns.modular.vpn.dto.UserQueryDTO;
import com.stylefeng.guns.modular.vpn.utils.ExportFileUtil;
import com.stylefeng.guns.modular.vpn.utils.LogUtil;
import com.stylefeng.guns.modular.vpn.utils.MD5Util;
import com.stylefeng.guns.modular.vpn.utils.PoiExcelUtil;
import com.stylefeng.guns.modular.vpn.vo.Paging;
import com.stylefeng.guns.modular.vpn.vo.UserListFilterDataVO;
import com.stylefeng.guns.modular.vpnuserinfo.service.IVpnUserInfoService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author stylefeng
 * @since 2020-03-02
 */
@Service
@Slf4j
public class VpnUserInfoServiceImpl extends ServiceImpl<VpnUserInfoMapper, VpnUserInfo> implements IVpnUserInfoService {
    @Autowired
    private VpnUserInfoMapper vpnUserInfoMapper;
    @Autowired
    private VpnPackageInfoMapper packageInfoMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;


    @Value("${push-msg-base-url}")
    private String pushBaseUrl;

    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public List<Map<String,Object>> findAllUsers(String userName,String beginTime,
                                                 String endTime,String packageId){
        return vpnUserInfoMapper.findAllUsers(userName,beginTime,endTime,packageId);
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public Paging findUserPage(UserQueryDTO userQueryDTO) {
        int start = userQueryDTO.getPage() > 0 ? userQueryDTO.getPage() - 1 : 0;
        int count = userQueryDTO.getLimit();
        userQueryDTO.setStart(start * count);
        userQueryDTO.setCount(count);
        Paging<Map<String, Object>> paging = new Paging<>();

        Long total = vpnUserInfoMapper.queryAllCount(userQueryDTO);
        List<Map<String, Object>> items = vpnUserInfoMapper.findUserPage(userQueryDTO);

        paging.setTotal(total);
        paging.setItems(items);

        return paging;
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public UserListFilterDataVO getFilterData() {
        UserListFilterDataVO dataVO = new UserListFilterDataVO();
        dataVO.setPackageList(packageInfoMapper.findPackageList());
        return dataVO;
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    public void exportExcel(String userName, String beginTime,
                            String endTime, String packageId,
                            HttpServletResponse response) {
        List< Map<String,Object>> dataList = null;
        List<String> headerList = new ArrayList<>();
        String sheetName = "用户数据";

        dataList = super.baseMapper.findAllUsers(userName,beginTime,endTime,packageId);
        headerList.add("用户名");
        headerList.add("注册IP");
        headerList.add("用户装置");
        headerList.add("注册版本号");
        headerList.add("注册时间");
        headerList.add("最后上线时间");
        headerList.add("上次使用支付渠道 ");
        headerList.add("用户支付次数");
        headerList.add("在用套餐");
        headerList.add("生效时间");
        headerList.add("失效时间");

        HSSFWorkbook workbook = new HSSFWorkbook();
        //创建一个Excel表单，参数为sheet的名字
        HSSFSheet sheet = workbook.createSheet(sheetName);

        //创建表头
        PoiExcelUtil.setTableHeader(workbook,sheet,headerList);
        //新增数据行，并且设置单元格数据
        ExportFileUtil.exportUserInfo(dataList,sheet);

        String fileName = "用户数据-"+System.currentTimeMillis()+".xls";
        //写入文件并将文件已二进制流的方式返回为调用者
        PoiExcelUtil.writeWorkBook(response,workbook,fileName);
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    @Transactional
    public void resetPwd(String userName, String pwd) {
        EntityWrapper<VpnUserInfo> entityWrapper = new EntityWrapper();
        entityWrapper.eq("username",userName);

        VpnUserInfo vpnUserInfo = selectOne(entityWrapper);

        if(vpnUserInfo == null){
            throw new GunsException(BizExceptionEnum.VPN_RESET_PWD_NOT_EXIST);
        }


        String regex = "^(?=.*[a-zA-Z])(?=.*\\d)[a-zA-Z\\d]{8,50}$";//大小写数字

        if(!Pattern.compile(regex).matcher(pwd).matches()){
            throw new GunsException(BizExceptionEnum.VPN_RESET_PWD_FORMAT_ERROR);
        }

        vpnUserInfo.setPassword(MD5Util.md5(pwd));
        updateById(vpnUserInfo);

        LogUtil.saveOperationLog("重置密码","给"+userName+"重置密码");
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    @Transactional
    public void disableUser(String userName, Integer status) {
        EntityWrapper<VpnUserInfo> wrapper = new EntityWrapper<>();
        wrapper.eq("username",userName);
        VpnUserInfo vpnUserInfo = new VpnUserInfo();
        vpnUserInfo.setUserName(userName);
        VpnUserInfo userInfo = this.baseMapper.selectOne(vpnUserInfo);
        if (userInfo == null){
            throw new GunsException(BizExceptionEnum.VPN_RESET_PWD_NOT_EXIST);
        }
        userInfo.setStatus(status);
        this.baseMapper.updateById(userInfo);
    }

    @Override
    @DataSource(name = DatasourceEnum.DATA_SOURCE_BIZ)
    @Transactional
    public Object addVipPackage(String userName, String packageId) {
        log.info("进入 添加VIP套餐>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        try {

            String adminToken = redisTemplate.opsForValue().get("adminToken");
            if(StringUtils.isEmpty(adminToken)){
                throw new GunsException(BizExceptionEnum.VPN_API_REDIS_NOT_TOKEN);
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("username",userName);
            jsonObject.put("packageId",packageId);
            jsonObject.put("token",adminToken);

            RestTemplate client = new RestTemplate();

            HttpHeaders headers = new HttpHeaders();
            headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
            HttpEntity<JSONObject> httpEntity = new HttpEntity(jsonObject,headers);

            JSONObject response =
                    client.postForEntity(pushBaseUrl+"/pay/vipbuy",
                            httpEntity,JSONObject.class).getBody();

            log.info("调用 添加VIP套餐接口返回：{}",response.toString());

            if(response.getInteger("code") != 0){
                return new ErrorTip(500,"添加VIP套餐失败");
            }
            VpnPackageInfo vpnPackageInfo = packageInfoMapper.selectById(packageId);

            LogUtil.saveOperationLog("添加VIP套餐","给"+userName+"添加了一个"+(vpnPackageInfo != null?vpnPackageInfo.getPackageName():"")+"套餐");
        } catch (Exception e) {
            e.printStackTrace();
            log.info("添加VIP套餐报错了：{}",e.getMessage());
            throw new GunsException(BizExceptionEnum.VPN_ADD_VIP_PACKAGE_FAIL);
        }
        log.info("结束 添加VIP套餐>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        return new SuccessTip();
    }
}
